#include "AIStrategy.h"
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <numeric>

// 基础评估函数实现
int AIStrategy::evaluateMove(const Board& board, const Pos& from, const Pos& to) {
    int score = 0;
    ChessDef::pieceID piece = board.getPieceAt(from);
    ChessDef::pieceID target = board.getPieceAt(to);
    
    // 基础吃子价值
    if (target != ChessDef::kong) {
        score += getPieceValue(target) * 2;
    }
    
    return score;
}

bool AIStrategy::willCauseFacingKings(const Board& board, const Pos& from, const Pos& to) {
    // 查找将帅位置
    Pos shuaiPos(-1, -1), jiangPos(-1, -1);
    
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            ChessDef::pieceID p = board.getPieceAt(Pos(row, col));
            if (p == ChessDef::shuai) {
                shuaiPos = Pos(row, col);
            } else if (p == ChessDef::jiang) {
                jiangPos = Pos(row, col);
            }
        }
    }
    
    // 如果有一个将帅不存在，返回false
    if (shuaiPos.row == -1 || jiangPos.row == -1) {
        return false;
    }
    
    // 在你的布局中，红方在左（列0-4），黑方在右（列5-9）
    // 将帅照面只可能发生在同一行且中间无棋子
    if (shuaiPos.row == jiangPos.row) {
        // 确保红帅在左，黑将在右
        if (shuaiPos.col < jiangPos.col) {
            int startCol = shuaiPos.col + 1;
            int endCol = jiangPos.col;
            bool isClear = true;
            
            // 检查中间列是否有棋子
            for (int c = startCol; c < endCol; c++) {
                if (board.getPieceAt(Pos(shuaiPos.row, c)) != ChessDef::kong) {
                    isClear = false;
                    break;
                }
            }
            
            if (isClear) {
                std::cout << "将帅照面: 红帅(" << shuaiPos.row << "," << shuaiPos.col 
                          << ") 黑将(" << jiangPos.row << "," << jiangPos.col 
                          << ") 中间无棋子" << std::endl;
                return true;
            }
        }
    }
    
    return false;
}

int AIStrategy::getPieceValue(ChessDef::pieceID piece) const {
    switch(piece) {
        case ChessDef::rche: case ChessDef::bche: return 1000;
        case ChessDef::rma: case ChessDef::bma: return 450;
        case ChessDef::rpao: case ChessDef::bpao: return 450;
        case ChessDef::rxiang: case ChessDef::bxiang: return 200;
        case ChessDef::rshi: case ChessDef::bshi: return 200;
        case ChessDef::bing: case ChessDef::zu: return 100;  // 修正：使用rbing和bzu
        case ChessDef::shuai: case ChessDef::jiang: return 10000;
        default: return 0;
    }
}

int AIStrategy::countOpenLines(const Board& board, const Pos& pos) {
    int openLines = 0;
    
    // 检查水平方向
    bool leftOpen = true, rightOpen = true;
    for (int c = 0; c < pos.col; c++) {
        if (board.getPieceAt(Pos(pos.row, c)) != ChessDef::kong) {
            leftOpen = false;
            break;
        }
    }
    for (int c = pos.col + 1; c < 10; c++) {
        if (board.getPieceAt(Pos(pos.row, c)) != ChessDef::kong) {
            rightOpen = false;
            break;
        }
    }
    if (leftOpen) openLines++;
    if (rightOpen) openLines++;
    
    // 检查垂直方向
    bool topOpen = true, bottomOpen = true;
    for (int r = 0; r < pos.row; r++) {
        if (board.getPieceAt(Pos(r, pos.col)) != ChessDef::kong) {
            topOpen = false;
            break;
        }
    }
    for (int r = pos.row + 1; r < 9; r++) {
        if (board.getPieceAt(Pos(r, pos.col)) != ChessDef::kong) {
            bottomOpen = false;
            break;
        }
    }
    if (topOpen) openLines++;
    if (bottomOpen) openLines++;
    
    return openLines;
}

// 中等AI专用评估函数
int MediumAIStrategy::evaluateMediumMove(const Board& board, const Pos& from, const Pos& to) {
    int score = evaluateMove(board, from, to);
    ChessDef::pieceID piece = board.getPieceAt(from);
    
    // 中等AI特有策略
    if (ChessDef::isBlack(piece)) {
        // 黑方向左移动（向红方进攻）
        if (to.col < from.col) {
            score += getPieceValue(piece) / 20;
        }
        
        // 保护将的安全
        if (piece == ChessDef::jiang) {
            if (to.col < 8 && to.col > 2) {
                score += 30;
            }
        }
        
        // 车炮的开放性奖励
        if (piece == ChessDef::bche || piece == ChessDef::bpao) {
            score += countOpenLines(board, to) * 3;
        }
    }
    
    return score;
}

// 困难AI专用评估函数
int HardAIStrategy::evaluateHardMove(Board& board, RuleChecker& ruleChecker, 
                                    const Pos& from, const Pos& to, int depth) {
    // 保存当前局面
    ChessDef::pieceID originalFrom = board.getPieceAt(from);
    ChessDef::pieceID originalTo = board.getPieceAt(to);
    
    // 执行走法
    board.movePiece(from, to);
    
    int score = evaluateMove(board, from, to);
    
    // 添加困难AI特有评估
    ChessDef::pieceID piece = originalFrom;
    if (ChessDef::isBlack(piece)) {
        // 战略位置评估
        if (piece == ChessDef::jiang) {
            // 将的位置安全评估
            if (to.col < 7 && to.col > 3) score += 50;
        }
        
        // 棋子协调性
        score += countOpenLines(board, to) * 5;
    }
    
    if (depth > 0) {
        // 考虑对手的最佳回应
        int opponentScore = evaluateBestOpponentMove(board, ruleChecker);
        score -= opponentScore / (depth + 1);
    }
    
    // 恢复局面
    board.setPieceAt(from, originalFrom);
    board.setPieceAt(to, originalTo);
    
    return score;
}

int HardAIStrategy::evaluateBestOpponentMove(Board& board, RuleChecker& ruleChecker) {
    int bestScore = 0;
    
    // 简化实现：评估几个关键走法
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            Pos from(row, col);
            ChessDef::pieceID piece = board.getPieceAt(from);
            
            if (piece != ChessDef::kong && ChessDef::isRed(piece)) {
                // 只检查有限的终点位置
                for (int toRow = std::max(0, row-1); toRow <= std::min(8, row+1); toRow++) {
                    for (int toCol = std::max(0, col-1); toCol <= std::min(9, col+1); toCol++) {
                        Pos to(toRow, toCol);
                        if (ruleChecker.isValidMove(from, to)) {
                            int moveScore = evaluateMove(board, from, to);
                            if (moveScore > bestScore) {
                                bestScore = moveScore;
                            }
                        }
                    }
                }
            }
        }
    }
    
    return bestScore;
}

int HardAIStrategy::evaluateBoard(const Board& board) {
    int score = 0;
    
    // 计算棋子价值差
    int blackValue = 0, redValue = 0;
    
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            ChessDef::pieceID piece = board.getPieceAt(Pos(row, col));
            if (piece != ChessDef::kong) {
                if (ChessDef::isBlack(piece)) {
                    blackValue += getPieceValue(piece);
                } else {
                    redValue += getPieceValue(piece);
                }
            }
        }
    }
    
    score = blackValue - redValue;
    return score;
}

// 简单AI策略实现 - 随机走法
bool SimpleAIStrategy::makeMove(Board& board, RuleChecker& ruleChecker) {
    std::vector<std::pair<Pos, Pos>> validMoves;
    
    // 收集所有黑方棋子的合法走法
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            Pos from(row, col);
            ChessDef::pieceID piece = board.getPieceAt(from);
            
            // 只处理黑方棋子（右侧，列5-9）
            if (piece != ChessDef::kong && ChessDef::isBlack(piece)) {
                for (int toRow = 0; toRow < 9; toRow++) {
                    for (int toCol = 0; toCol < 10; toCol++) {
                        Pos to(toRow, toCol);
                        if (ruleChecker.isValidMove(from, to)) {
                            // 保存当前棋盘状态
                            ChessDef::pieceID targetPiece = board.getPieceAt(to);
                            
                            // 模拟移动
                            board.movePiece(from, to);
                            
                            // 检查移动后是否会导致将帅照面
                            bool causesFacing = willCauseFacingKings(board, from, to);
                            
                            // 恢复棋盘
                            board.setPieceAt(from, piece);
                            board.setPieceAt(to, targetPiece);
                            
                            // 如果会导致照面，跳过这个走法
                            if (causesFacing) {
                                std::cout << "跳过会导致照面的走法: (" << from.row << "," << from.col 
                                          << ")->(" << to.row << "," << to.col << ")" << std::endl;
                                continue;
                            }
                            
                            validMoves.push_back(std::make_pair(from, to));
                        }
                    }
                }
            }
        }
    }
    
    if (!validMoves.empty()) {
        int randomIndex = rand() % validMoves.size();
        Pos from = validMoves[randomIndex].first;
        Pos to = validMoves[randomIndex].second;
        
        std::cout << "简单AI走棋: (" << from.row << "," << from.col << ")->(" 
                  << to.row << "," << to.col << ")" << std::endl;
        
        return board.movePiece(from, to);
    }
    
    std::cout << "简单AI无合法走法" << std::endl;
    return false;
}
// 中等AI策略实现 - 基础规则评估
bool MediumAIStrategy::makeMove(Board& board, RuleChecker& ruleChecker) {
    std::vector<ScoredMove> moves;
    
    // 收集所有黑方棋子的走法并评分
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            Pos from(row, col);
            ChessDef::pieceID piece = board.getPieceAt(from);
            
            if (piece != ChessDef::kong && ChessDef::isBlack(piece)) {
                for (int toRow = 0; toRow < 9; toRow++) {
                    for (int toCol = 0; toCol < 10; toCol++) {
                        Pos to(toRow, toCol);
                        if (ruleChecker.isValidMove(from, to)) {
                            // 保存当前棋盘状态
                            ChessDef::pieceID targetPiece = board.getPieceAt(to);
                            
                            // 模拟移动
                            board.movePiece(from, to);
                            
                            // 检查移动后是否会导致将帅照面
                            bool causesFacing = willCauseFacingKings(board, from, to);
                            
                            // 恢复棋盘
                            board.setPieceAt(from, piece);
                            board.setPieceAt(to, targetPiece);
                            
                            // 如果会导致照面，跳过这个走法
                            if (causesFacing) {
                                std::cout << "中等AI跳过会导致照面的走法: (" << from.row << "," << from.col 
                                          << ")->(" << to.row << "," << to.col << ")" << std::endl;
                                continue;
                            }
                            
                            // 使用中等AI专用评估函数
                            int score = evaluateMediumMove(board, from, to);
                            moves.push_back(ScoredMove(from, to, score));
                        }
                    }
                }
            }
        }
    }
    
    if (!moves.empty()) {
        // 按分数排序，选择最佳走法
        std::sort(moves.begin(), moves.end(), [](const ScoredMove& a, const ScoredMove& b) {
            return a.score > b.score;
        });
        
        // 在前25%的走法中随机选择，增加变化性
        int bestCount = std::max(1, (int)(moves.size() * 0.25));
        int selected = rand() % bestCount;
        
        Pos from = moves[selected].from;
        Pos to = moves[selected].to;
        
        std::cout << "中等AI走棋: (" << from.row << "," << from.col << ")->(" 
                  << to.row << "," << to.col << ") 评分:" << moves[selected].score << std::endl;
        
        return board.movePiece(from, to);
    }
    
    std::cout << "中等AI无合法走法" << std::endl;
    return false;
}

// 困难AI策略实现 - 高级算法
bool HardAIStrategy::makeMove(Board& board, RuleChecker& ruleChecker) {
    std::vector<ScoredMove> moves;
    
    // 深度搜索最佳走法
    for (int row = 0; row < 9; row++) {
        for (int col = 0; col < 10; col++) {
            Pos from(row, col);
            ChessDef::pieceID piece = board.getPieceAt(from);
            
            if (piece != ChessDef::kong && ChessDef::isBlack(piece)) {
                for (int toRow = 0; toRow < 9; toRow++) {
                    for (int toCol = 0; toCol < 10; toCol++) {
                        Pos to(toRow, toCol);
                        if (ruleChecker.isValidMove(from, to)) {
                            // 保存当前棋盘状态
                            ChessDef::pieceID targetPiece = board.getPieceAt(to);
                            
                            // 模拟移动
                            board.movePiece(from, to);
                            
                            // 检查移动后是否会导致将帅照面
                            bool causesFacing = willCauseFacingKings(board, from, to);
                            
                            // 恢复棋盘
                            board.setPieceAt(from, piece);
                            board.setPieceAt(to, targetPiece);
                            
                            // 如果会导致照面，跳过这个走法
                            if (causesFacing) {
                                std::cout << "困难AI跳过会导致照面的走法: (" << from.row << "," << from.col 
                                          << ")->(" << to.row << "," << to.col << ")" << std::endl;
                                continue;
                            }
                            
                            // 使用困难AI专用评估函数（深度设为2）
                            int score = evaluateHardMove(board, ruleChecker, from, to, 2);
                            moves.push_back(ScoredMove(from, to, score));
                        }
                    }
                }
            }
        }
    }
    
    if (!moves.empty()) {
        // 选择最佳走法
        auto bestMove = std::max_element(moves.begin(), moves.end(), 
            [](const ScoredMove& a, const ScoredMove& b) { return a.score < b.score; });
        
        Pos from = bestMove->from;
        Pos to = bestMove->to;
        
        std::cout << "困难AI走棋: (" << from.row << "," << from.col << ")->(" 
                  << to.row << "," << to.col << ") 评分:" << bestMove->score << std::endl;
        
        return board.movePiece(from, to);
    }
    
    std::cout << "困难AI无合法走法" << std::endl;
    return false;
}